<template>
  <!-- 密评使用登录页 -->
  <el-form ref="loginForm" :model="loginForm" :rules="rules" size="medium">
    <el-form-item prop="loginName" class="user" :class="{ warn: userWarning }">
      <i class="inp-icon el-icon-user"></i>
      <el-input
        v-model="loginForm.loginName"
        name="loginName"
        placeholder="请输入用户名或者手机号"
        @focus="userWarning = false" />
      <span class="err-tip" v-show="userWarning">{{ errWarning }}</span>
    </el-form-item>
    <el-form-item prop="loginPassword" class="password" :class="{ warn: passwordWarning }">
      <i class="inp-icon el-icon-lock"></i>
      <el-input
        v-model="loginForm.loginPassword"
        :type="inputStyle"
        name="loginPassword"
        label="密码"
        placeholder="请输入密码"
        @keyup.enter.native="alyOnSubmit"
        @focus="passwordWarning = false">
        <span slot="suffix" @click="typeStyle" class="icon-box">
          <i class="el-input__icon iconfont icon-biyan" v-show="inputStyle === 'password'"></i>
          <i class="el-input__icon iconfont icon-zhengyan-01" v-show="inputStyle === 'text'"></i>
        </span>
      </el-input>
      <span class="err-tip" v-show="passwordWarning">{{ errWarning }}</span>
    </el-form-item>
    <div class="commit">
      <div class="btn" v-loading="loading" @click="alyOnSubmit">登 录</div>
    </div>
    <div class="drive-tips">
      <div class="down-tips">
        如果您还未安装CA数字证书助手，请先
        <a v-if="isWindow" class="download-drive" href="https://online.aheca.cn/cams/exeVersionApi/newExeVersion">
          下载驱动
        </a>
        <template v-else>
          <a class="download-drive" :href="`${downloadUrl}com.longmai.mpluginv4_x86.deb`">下载驱动1(X86)，</a>
          <a class="download-drive" :href="`${downloadUrl}signed_com.longmai.mpluginv4_arm64.deb`">驱动2(ARM64)</a>
        </template>
      </div>
      <div class="other-service">
        有关数字证书更多信息，请查询
        <a class="download-drive" href="https://online.aheca.cn/ocss/portal/customer-service" target="_blank">
          数字证书网上服务厅
        </a>
      </div>
      <!-- <div :class="['warning', !isWindow ? 'linux-warning' : '']">安装CA助手时请不要插入UKey。</div> -->
      <div :class="['warning', !isWindow ? 'linux-warning' : '']">首次使用UKey时，建议您使用助手修改初始密码。</div>
    </div>
  </el-form>
</template>
<script>
import { getLoginRandomNumber, verifyCertAuth } from '@api/modules/user'
import { Loading } from 'element-ui'
export default {
  name: 'CaAccountForm',
  emits: ['login-success', 'show-dialog'],
  data() {
    return {
      // 阿里云登录
      loginForm: {
        loginName: '',
        loginPassword: '',
      },
      rules: {
        loginName: [{ required: true, message: '请填写用户名', trigger: 'blur' }],
        loginPassword: [{ required: true, message: '请填写密码', trigger: 'blur' }],
      },
      inputStyle: 'password',
      errWarning: '',
      userWarning: false,
      passwordWarning: false,
      // CA
      loading: false,
      UKVersion: '',
      downloadUrl: '',
      signStr: '',
      loadServe: null,
      isWindow: true,
      ukeyHelper: null,
    }
  },
  created() {
    this.judgeSystem()
    if (!this.isWindow) {
      const { origin, pathname } = location
      this.downloadUrl = `${origin}${pathname.replace('index.html', '')}`
      // eslint-disable-next-line
      this.ukeyHelper = window.mToken && new window.mToken('mTokenPlugin')
    }
    this.checkVersion()
  },
  mounted() {
    this.logInfo()
  },
  methods: {
    // 判断系统
    judgeSystem() {
      const { platform = '', userAgent = '' } = window.navigator || {}
      if (userAgent.indexOf('Windows') > -1 || platform.indexOf('Win') > -1) {
        this.isWindow = true
      } else {
        this.isWindow = false
      }
    },
    // 验证CA助手是否打开
    async checkVersion() {
      this.loading = true
      if (this.isWindow) {
        // eslint-disable-next-line
        const { createParams, getAjaxResult, AjaxIO_YB } = window
        if (createParams) {
          const params = createParams('getVersion')
          AjaxIO_YB(params, () => {
            const result = getAjaxResult()
            this.loading = false
            if (result) {
              if (String(result.retCode) === '0') {
                this.UKVersion = result.version || ''
              } else {
                this.UKVersion = ''
              }
            } else {
              this.UKVersion = ''
            }
          })
        } else {
          this.UKVersion = ''
        }
      } else {
        await this.enumDevice()
        this.loading = false
        this.UKVersion = await this.ukeyHelper.SOF_GetVersion()
      }
    },
    enumDevice() {
      this.ukeyHelper && this.ukeyHelper.SOF_LoadLibrary(this.ukeyHelper.GM3000)
    },
    startLoading() {
      this.loadServe = Loading.service({
        lock: true,
        text: '加载中...',
        background: 'rgba(255,255,255,0.5)',
      })
    },
    alertFunc(type, txt = '') {
      this.loading = false
      let tips = ''
      if (type === '1') {
        tips = `<div style="padding:20px 30px; text-align:center;">
        <svg t="1667971619933" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="856" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100"><path d="M509.695003 631.614262c16.666588 0 30.133298-13.468756 30.133298-30.134321l0-271.145443c0-16.666588-13.46671-30.134321-30.133298-30.134321-16.635889 0-30.135344 13.467733-30.135344 30.134321l0 271.145443C479.559659 618.145505 493.059114 631.614262 509.695003 631.614262z" p-id="857"></path><path d="M509.695003 692.003654c-24.938995 0-45.201481 20.231787-45.201481 45.201481s20.263509 45.201481 45.201481 45.201481c24.966625 0 45.201481-20.231787 45.201481-45.201481S534.661627 692.003654 509.695003 692.003654z" p-id="858"></path><path d="M915.211806 753.440911l-320.651974-574.146409c-20.907169-37.390585-51.90209-58.792011-85.050048-58.792011-33.209356 0-64.204277 21.401426-85.052095 58.82271L104.114754 753.379513c-20.694321 37.205367-22.754237 75.149561-5.719258 104.301508 17.0974 29.088502 51.28913 45.815465 93.877087 45.815465l634.875538 0c42.526559 0 76.750011-16.666588 93.817736-45.75509C938.059164 828.592518 935.936827 790.647301 915.211806 753.440911zM869.025904 827.177286c-6.025227 10.270924-21.246907 16.051581-41.879829 16.051581L192.27156 843.228867c-20.6012 0-35.883255-5.843078-41.879829-16.051581-5.996574-10.148128-3.659343-26.38288 6.395664-44.338834L477.09963 208.691019c9.778714-17.496489 21.893636-27.981285 32.43983-27.981285 10.516518 0 22.63144 10.485819 32.378431 27.981285l320.682673 574.147432C872.686271 800.855804 874.96108 817.029158 869.025904 827.177286z" p-id="859"></path></svg>
        <div style="margin-top:20px;font-size:16px;color:#333;line-height:1.5">${
          txt || '驱动服务加载异常，请重新安装助手或者请重启电脑后重试。'
        }</div>
        </div>`
      } else if (type === '2') {
        tips = `<div style="padding:20px 30px; text-align:center;">
        <svg t="1667973934615" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="828" width="100" height="100">
        <path d="M704 736m-256 0a256 256 0 1 0 512 0 256 256 0 1 0-512 0Z" fill="#ffffff" p-id="829"></path><path d="M256 128h64v64H256zM384 128h64v64h-64z" fill="#d1bfa9" p-id="830"></path>
        <path d="M704 448c-10.816 0-21.472 0.704-32 1.888V448c0-59.456-40.96-109.12-96-123.456V32a32 32 0 0 0-32-32H160a32 32 0 0 0-32 32v292.544c-55.04 14.304-96 64-96 123.456v448c0 70.592 57.408 128 128 128h384c22.272 0 43.68-6.016 63.008-17.152A286.016 286.016 0 0 0 704 1024c158.816 0 288-129.216 288-288s-129.184-288-288-288zM192 64h320v256H192V64zM160 960c-35.296 0-64-28.704-64-64V448c0-35.296 28.704-64 64-64h384c35.296 0 64 28.704 64 64v16.8c-111.68 39.68-192 146.112-192 271.2a287.456 287.456 0 0 0 107.392 224H160z m544 0c-123.52 0-224-100.48-224-224s100.48-224 224-224 224 100.48 224 224-100.48 224-224 224z" fill="#d1bfa9" p-id="831"></path>
        <path d="M822.624 617.376a32 32 0 0 0-45.248 0L704 690.752l-73.376-73.376a32 32 0 1 0-45.248 45.248L658.752 736l-73.376 73.376a32 32 0 1 0 45.248 45.248L704 781.248l73.376 73.376a31.904 31.904 0 0 0 45.248 0 32 32 0 0 0 0-45.248L749.248 736l73.376-73.376a32 32 0 0 0 0-45.248z" fill="#d1bfa9" p-id="832"></path></svg>
        <div style="margin-top:20px;font-size:16px;color:#333;line-height:1.5">${
          txt || '未读取到UKey信息，请检查UKey插入是否正常。'
        }</div>
        </div>`
      }
      if (tips) {
        this.$alert(tips, '企业数字证书登录', {
          customClass: 'no-usbkey-tips',
          showConfirmButton: false,
          dangerouslyUseHTMLString: true,
          closeOnClickModal: true,
        })
      }
    },
    endLoading() {
      this.loadServe && this.loadServe.close()
      this.loading = false
    },
    // 获取后端的字符串签名（CA认证中心生成的随机数）
    async getStringSign() {
      const { data = '', status = 0 } = await getLoginRandomNumber({ ...this.loginForm })
      if (status === 200 && data) {
        this.signStr = data
      } else {
        this.signStr = ''
      }
    },
    // 阿里云登录
    alyOnSubmit() {
      this.$refs.loginForm.validate(async valid => {
        if (!valid) {
          return
        }
        this.loading = true
        await this.getStringSign()

        if ((!this.UKVersion && this.isWindow) || !this.signStr) {
          if (!this.UKVersion) {
            this.alertFunc('1')
          } else if (!this.signStr) {
            this.alertFunc('1', 'CA认证中心授权无效，请联系管理员处理异常。')
          }
          return
        }
        if (this.isWindow) {
          this.certLogin()
        } else {
          this.certLoginLinux()
        }
      })
    },
    resSuccess(res) {
      if (res.status === 200) {
        localStorage.setItem('efficacy_loginName', this.loginForm.loginName)
        localStorage.setItem('efficacy_loginPassword', window.btoa(this.loginForm.loginPassword))
        this.$emit('login-success', res.data || {})
        this.passwordWarning = false
        this.userWarning = false
      } else if (res.status === 500) {
        this.errWarning = res.message
        if (res.message.indexOf('密码错误') !== -1) {
          this.passwordWarning = true
        } else if (res.message.indexOf('用户不存在') !== -1) {
          this.userWarning = true
        }
      }
    },
    logInfo() {
      const loginName = localStorage.getItem('efficacy_loginName')
      const loginPassword = localStorage.getItem('efficacy_loginPassword')
      if (loginPassword) {
        this.loginForm.loginName = loginName
        this.loginForm.loginPassword = window.atob(loginPassword)
      }
    },
    typeStyle() {
      this.inputStyle = this.inputStyle === 'password' ? 'text' : 'password'
    },
    // 验证CA证书密码并对随机数签名
    certLogin() {
      this.$prompt('请输入UKey密码', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputType: 'password',
        inputPlaceholder: '请输入UKey的PIN码（密码），错误5次将会锁定UKey！',
        inputPattern: /^[0-9]{6,10}$/,
        inputErrorMessage: '请输入6-10位数字密码',
      })
        .then(({ value }) => {
          this.startLoading()
          const certPwd = value
          if (certPwd) {
            // eslint-disable-next-line
            const { createParams, getAjaxResult, AjaxIO_YB } = window
            if (createParams) {
              const signType = 'P1' // 签名类型
              const signCount = 1 // 签名次数
              const jsonStr = createParams('SOF_QuickSign', signCount, this.signStr, signType, certPwd)
              // const params = createParams('SOF_Auth_YB', this.signStr, certPwd, signType)
              AjaxIO_YB(jsonStr, () => {
                this.loading = false
                // 获取签名结果、证书信息、序列号
                const result = getAjaxResult()
                if (result) {
                  if (String(result.retCode) === '0') {
                    // 将签名信息发送到服务端进行验证，验证成功便可登录
                    // keysn-KEY序列号，signdata-签名结果，certdata-证书信息
                    const { signdata = '', certdata = '' } = result || {}
                    verifyCertAuth({
                      randomNum: this.signStr,
                      strSignData: signdata,
                      strUkeySn: '',
                      certdata: certdata,
                    })
                      .then(res => {
                        this.endLoading()
                        // if (res.status == 200) {
                        //   this.$emit('login-success', res.data || {})
                        // }
                        this.resSuccess(res)
                      })
                      .catch(() => {
                        this.endLoading()
                      })
                  } else {
                    this.endLoading()
                    this.checkVersion()
                    if (result.retMsg && result.retMsg.indexOf('PIN') > -1) {
                      this.alertFunc('1', '请输入正确的PIN码，多次错误输入会锁死UKey！')
                    } else if (result.retMsg && result.retMsg.toLocaleLowerCase().indexOf('ukey') > -1) {
                      this.alertFunc('2', '读取不到UKey，请确保UKey插入正常。')
                    } else if (result.retMsg) {
                      this.alertFunc('1', result.retMsg)
                    } else {
                      this.alertFunc('1', 'CA认证中心服务异常，请联系管理员处理。')
                    }
                  }
                }
              })
            } else {
              this.loading = false
              this.endLoading()
              this.checkVersion()
            }
          } else {
            this.loading = false
            this.endLoading()
            this.checkVersion()
          }
        })
        .catch(() => {
          this.loading = false
          this.endLoading()
          this.$message({
            type: 'info',
            message: '取消输入',
          })
        })
    },
    // 验证Linux系统登录
    certLoginLinux() {
      this.$prompt('请输入UKey密码', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputType: 'password',
        inputPlaceholder: '请输入UKey的PIN码（密码），错误5次将会锁定UKey！',
        inputPattern: /^[0-9]{6,10}$/,
        inputErrorMessage: '请输入6-10位数字密码',
      })
        .then(({ value }) => {
          this.startLoading()
          const certPwd = value
          if (certPwd) {
            // eslint-disable-next-line
            const token = new window.mToken('mTokenPlugin')
            // 1. 加载lib库
            const loadResult = token.SOF_LoadLibrary(token.GM3000)
            if (String(loadResult) !== '0') {
              this.endLoading()
              this.alertFunc('1')
              return
            }
            // 获取UKey序列号
            const deviceList = token.SOF_EnumDevice()
            let keysn = '' // 序列号
            if (deviceList && deviceList.length) {
              keysn = deviceList[0]
            } else {
              this.alertFunc('2')
              this.endLoading()
              return
            }
            // 2. 验证密码
            token.SOF_GetDeviceInstance(keysn, '')
            const loginResult = token.SOF_Login(certPwd)
            if (String(loginResult) !== '0') {
              this.alertFunc('1', '请输入正确的PIN码，多次错误输入会锁死UKey！')
              this.endLoading()
              return
            }
            // 3. 获取UKey证书
            const constainers = token.SOF_EnumCertContiner().split('||')
            if (constainers.length === 0) {
              this.alertFunc('2')
              this.endLoading()
              return
            }
            const containerName = constainers[0]

            const certType = '1' // SGD_SM3
            // 获取证书信息
            const signCert = token.SOF_ExportUserCert(containerName, certType)
            // 签名
            token.SOF_SetDigestMethod(1) // SGD_SM3

            const { _Base64encode } = window

            // 获取签名结果
            const signedRsult = token.SOF_SignData(
              containerName,
              certType,
              _Base64encode(this.signStr),
              this.signStr.length,
              0
            )
            if (!signedRsult) {
              this.alertFunc('2', '获取签名失败，请刷新页面重试。')
              this.endLoading()
              return
            }
            verifyCertAuth({ randomNum: this.signStr, strSignData: signedRsult, strUkeySn: '', certdata: signCert })
              .then(res => {
                this.loading = false
                this.endLoading()
                // if (res.status == 200) {
                //   this.$emit('login-success', res.data || {})
                // }
                this.resSuccess(res)
              })
              .catch(() => {
                this.endLoading()
              })
          } else {
            this.endLoading()
            this.checkVersion()
          }
        })
        .catch(() => {
          this.endLoading()
          this.$message({
            type: 'info',
            message: '取消输入',
          })
        })
    },
  },
}
</script>
<style lang="scss" scoped>
.el-form {
  .el-form-item {
    .icon-box {
      cursor: pointer;
      .iconfont {
        font-size: 0.4rem;
        line-height: 0.4rem;
        color: #767676;
      }
    }
    .password,
    .user {
      .err-tip {
        position: absolute;
        left: 0;
        bottom: -22px;
        line-height: 22px;
        color: #fc6969;
        font-size: 12px;
      }
    }
    .warn {
      .el-input__inner {
        border-color: #fc6969;
      }
    }
  }

  .commit {
    margin-top: 0.3rem;
    cursor: pointer;
    .btn {
      height: 0.4rem;
      background-color: #b72c25;
      color: #fff;
      font-size: 0.2rem;
      text-align: center;
      line-height: 0.4rem;
    }
  }
  .drive-tips {
    margin-top: 0.3rem;
    .down-tips,
    .other-service {
      margin-top: 0.1rem;
      text-align: center;
      font-size: 0.14rem;
      line-height: 1.5;
      color: #333;
      .download-drive {
        color: #567fe6;
        cursor: pointer;
      }
    }
    .down-img {
      margin-top: 0.1rem;
      text-align: center;
      .image-viewer-box,
      img {
        cursor: pointer;
      }
    }
    .warning {
      margin-top: 0.3rem;
      text-align: center;
      color: #d1bfa9;
      font-size: 0.14rem;
      &.linux-warning {
        margin-top: 0.15rem;
      }
    }
  }
}
</style>
